import os
import json
import sys
from datetime import datetime, timedelta

from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from django.db import connection
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

from langchain_community.embeddings import DashScopeEmbeddings, HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import DirectoryLoader
import pickle

from ai.Ser import CustomerServiceChatSer
from ai.models import CustomerServiceChat
from ai.agents.tools.data_collection_tool import data_collection_tool
from ai.agents.tools.similarity_calculation_tool import similarity_calculation_tool
from ai.agents.tools.area_recommendation_tool import area_recommendation_tool
from ai.agents.dispatch_graph import create_dispatch_graph, create_hotspot_graph

from ai.services.smart_customer_service import SmartCustomerService
from ai.services.data_crawler import DataCrawler
from ai.services.data_manager import DataManager

# 添加项目路径
sys.path.append(os.path.dirname(os.path.dirname(__file__)))

embeddings = DashScopeEmbeddings(
    dashscope_api_key=os.getenv("DASHSCOPE_API_KEY"),
    model="text-embedding-v4"
)
llm = ChatOpenAI(
    model="qwen-max",
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

# 文档搜索功能

# 文档搜索功能
def search_docs(query, k=3):
    # 从本地加载FAISS索引
    try:
        embeddings = HuggingFaceEmbeddings(model_name="shibing624/text2vec-base-chinese")
        vectorstore = FAISS.load_local("index", embeddings)
        docs = vectorstore.similarity_search(query, k=k)
        return docs
    except Exception as e:
        print(f"文档搜索失败: {e}")
        return []

def rag_qa(question):
    # 在文档库中搜索与问题相关的文档，并返回前3个文档的内容
    docs = search_docs(question, k=3)
    context = "\n".join([doc.page_content for doc in docs])
    # 定义一个聊天提示模板，用于回答问题
    prompt = ChatPromptTemplate.from_template(
        """
        您好，我是滴滴出行车主端智能客服。请严格依据以下上下文内容 {context}，为员工解答问题：{question}。
        回答要求：
        1. 只引用上下文中的信息，不添加外部知识或主观推测；
        2. 针对员工问题，清晰、准确地引用文档中的具体条款、流程或数据（如条款编号、表格内容、具体天数/比例等）；
        3. 回答风格需正式、专业且亲切，体现人事客服的服务意识，让员工感受到关怀；
        4. 如上下文未明确涉及员工问题的答案，请回复："很抱歉，根据现有文档暂未提及相关信息，建议您联系HR部门进一步确认。"，不得编造内容；
        5. 结尾可加"如有其他疑问，欢迎随时咨询人事客服！"。
        请用智能客服的口吻作答。
        """
    )
    # 将聊天提示模板与语言模型结合
    chain = prompt | llm
    # 调用语言模型，返回回答问题的内容
    return chain.invoke({"context": context, "question": question}).content

@method_decorator(csrf_exempt, name='dispatch')
class AiChatView(APIView):
    def get(self, request):
        return Response({
            "code": 200,
            "message": "智能客服系统已就绪",
            "data": {
                "system": "智能客服系统",
                "version": "1.0.0"
            }
        })
    
    def post(self, request):
        # 获取参数
        try:
            data = json.loads(request.body)
            question = data.get('question', '')
            
            if not question:
                return Response({
                    "code": 400,
                    "message": "问题不能为空"
                }, status=400)
            
            # 使用RAG回答问题
            answer = rag_qa(question)
            
            return Response({
                "code": 200,
                "message": "回答成功",
                "data": {
                    "question": question,
                    "answer": answer,
                    "timestamp": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                }
            })
            
        except json.JSONDecodeError:
            return Response({
                "code": 400,
                "message": "请求格式错误"
            }, status=400)
        except Exception as e:
            return Response({
                "code": 500,
                "message": f"处理失败: {str(e)}"
            }, status=500)
    
    def delete(self, request):
        return Response({
            "code": 200,
            "message": "聊天记录已清空"
        })

# 调度推荐视图 - 使用LangGraph
class DispatchRecommendationView(APIView):
    def post(self, request):
        try:
            driver_id = request.data.get("driver_id")
            time_category = request.data.get("time_category", "morning_peak")
            
            if not driver_id:
                return Response({"code": 400, "message": "司机ID不能为空"}, status=400)
            
            # 确保driver_id是整数
            try:
                driver_id = int(driver_id)
            except (ValueError, TypeError):
                return Response({"code": 400, "message": "司机ID格式错误"}, status=400)
            
            # 使用LangGraph工作流
            graph = create_dispatch_graph()
            
            # 初始化状态
            initial_state = {
                "driver_id": driver_id,
                "time_category": time_category,
                "data_file": "",
                "similar_drivers": [],
                "recommendations": [],
                "error": "",
                "success": False,
                "actual_time_category": time_category
            }
            
            # 执行工作流
            result = graph.invoke(initial_state)
            
            # 检查结果
            if not result["success"]:
                return Response({
                    "code": 500,
                    "message": f"调度推荐失败: {result['error']}"
                }, status=500)
            
            # 构建响应消息
            message = "调度推荐成功"
            if result["actual_time_category"] != time_category:
                message = f"调度推荐成功（已自动调整为{result['actual_time_category']}时段）"
            
            return Response({
                "code": 200,
                "message": message,
                "data": {
                    "recommendations": result["recommendations"],
                    "similar_drivers": result["similar_drivers"],
                    "requested_time_category": time_category,
                    "actual_time_category": result["actual_time_category"],
                    "analysis_date": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                }
            })
            
        except Exception as e:
            return Response({
                "code": 500,
                "message": f"调度推荐失败: {str(e)}"
            }, status=500)

# 热点分析视图 - 使用LangGraph
class HotspotAnalysisView(APIView):
    def get(self, request):
        try:
            time_category = request.query_params.get("time_category", "morning_peak")
            
            # 使用LangGraph工作流
            graph = create_hotspot_graph()
            
            # 初始化状态（使用默认司机ID）
            initial_state = {
                "driver_id": 51,  # 默认司机ID
                "time_category": time_category,
                "data_file": "",
                "similar_drivers": [],
                "recommendations": [],
                "error": "",
                "success": False,
                "actual_time_category": time_category
            }
            
            # 执行工作流
            result = graph.invoke(initial_state)
            
            # 检查结果
            if not result["success"]:
                return Response({
                    "code": 500,
                    "message": f"热点分析失败: {result['error']}"
                }, status=500)
            
            # 解析数据收集结果获取统计信息
            try:
                data_query = json.dumps({
                    "days": 7,
                    "output_file": f"hotspot_analysis_{time_category}.csv",
                    "time_category": time_category
                })
                data_result = data_collection_tool.invoke(data_query)
                
                if "数据收集完成：" in data_result:
                    data_json_str = data_result.split("数据收集完成：")[1]
                    data_stats = json.loads(data_json_str)
                else:
                    data_stats = {"total_records": 0, "unique_drivers": 0, "unique_areas": 0}
            except Exception as e:
                print(f"解析热点分析数据失败: {e}")
                data_stats = {"total_records": 0, "unique_drivers": 0, "unique_areas": 0}
            
            return Response({
                "code": 200,
                "message": "热点分析成功",
                "data": {
                    "analysis_result": json.dumps(data_stats, ensure_ascii=False)
                }
            })
            
        except Exception as e:
            return Response({
                "code": 500,
                "message": f"热点分析失败: {str(e)}"
            }, status=500)

# 调度效果跟踪视图
class DispatchEffectsView(APIView):
    def get(self, request):
        try:
            driver_id = request.query_params.get("driver_id")
            days = int(request.query_params.get("days", 7))
            
            if not driver_id:
                return Response({"code": 400, "message": "司机ID不能为空"}, status=400)
            
            # 确保driver_id是整数
            try:
                driver_id = int(driver_id)
            except (ValueError, TypeError):
                return Response({"code": 400, "message": "司机ID格式错误"}, status=400)
            
            # 从数据库查询真实效果数据
            from ai.models import DispatchRecord, DriverPerformance
            from datetime import datetime, timedelta
            
            end_date = datetime.now()
            start_date = end_date - timedelta(days=days)
            
            # 查询调度记录
            dispatch_records = DispatchRecord.objects.filter(
                driver_id=driver_id,
                created_at__gte=start_date
            )
            
            # 查询司机表现
            performance_records = DriverPerformance.objects.filter(
                driver_id=driver_id,
                date__gte=start_date.date()
            )
            
            # 计算效果指标
            total_dispatches = dispatch_records.count()
            accepted_dispatches = dispatch_records.filter(accepted=True).count()
            executed_dispatches = dispatch_records.filter(executed=True).count()
            
            acceptance_rate = accepted_dispatches / max(total_dispatches, 1)
            success_rate = executed_dispatches / max(accepted_dispatches, 1)
            
            # 计算收入增长
            total_revenue = sum([record.revenue_generated or 0 for record in dispatch_records if record.revenue_generated])
            avg_orders_increase = sum([record.orders_completed for record in dispatch_records]) / max(total_dispatches, 1)
            
            effects_data = {
                "dispatch_count": total_dispatches,
                "acceptance_rate": round(acceptance_rate, 2),
                "success_rate": round(success_rate, 2),
                "revenue_increase": round(total_revenue, 2),
                "avg_orders_increase": round(avg_orders_increase, 1),
                "analysis_period": f"{days}天",
                "analysis_date": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            }
            
            return Response({
                "code": 200,
                "message": "效果查询成功",
                "data": effects_data
            })
            
        except Exception as e:
            return Response({
                "code": 500,
                "message": f"效果查询失败: {str(e)}"
            }, status=500)
    
    def post(self, request):
        try:
            driver_id = request.data.get("driver_id")
            area_id = request.data.get("area_id")
            accepted = request.data.get("accepted", False)
            time_category = request.data.get("time_category", "normal")
            recommendation_score = request.data.get("recommendation_score", 0.0)
            
            if not driver_id or not area_id:
                return Response({"code": 400, "message": "参数不完整"}, status=400)
            
            # 确保driver_id是整数
            try:
                driver_id = int(driver_id)
            except (ValueError, TypeError):
                return Response({"code": 400, "message": "司机ID格式错误"}, status=400)
            
            # 记录调度结果到数据库
            from ai.models import DispatchRecord
            
            dispatch_record = DispatchRecord.objects.create(
                driver_id=driver_id,
                area_id=area_id,
                time_category=time_category,
                recommendation_score=recommendation_score,
                accepted=accepted
            )
            
            return Response({
                "code": 200,
                "message": "调度结果记录成功",
                "data": {
                    "driver_id": driver_id,
                    "area_id": area_id,
                    "accepted": accepted,
                    "record_id": dispatch_record.id,
                    "record_time": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                }
            })
            
        except Exception as e:
            return Response({
                "code": 500,
                "message": f"记录失败: {str(e)}"
            }, status=500)


@method_decorator(csrf_exempt, name='dispatch')
class SmartCustomerServiceView(APIView):
    """智能客服API"""
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.service = SmartCustomerService()
    
    def post(self, request):
        """处理客户查询"""
        try:
            data = json.loads(request.body)
            question = data.get('question', '')
            user_id = data.get('user_id', None)
            
            if not question:
                return Response({
                    "code": 400,
                    "message": "问题不能为空",
                    "data": None
                }, status=status.HTTP_400_BAD_REQUEST)
            
            # 处理查询
            result = self.service.process_customer_query(question, user_id)
            
            return Response({
                "code": 200,
                "message": "查询处理成功",
                "data": result
            })
            
        except Exception as e:
            return Response({
                "code": 500,
                "message": f"处理查询失败: {str(e)}",
                "data": None
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    def get(self, request):
        """获取知识库统计信息"""
        try:
            stats = self.service.get_knowledge_statistics()
            
            return Response({
                "code": 200,
                "message": "获取统计信息成功",
                "data": stats
            })
            
        except Exception as e:
            return Response({
                "code": 500,
                "message": f"获取统计信息失败: {str(e)}",
                "data": None
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@method_decorator(csrf_exempt, name='dispatch')
class KnowledgeBaseView(APIView):
    """知识库管理API"""
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.service = SmartCustomerService()
        self.crawler = DataCrawler()
    
    def post(self, request):
        """更新知识库"""
        try:
            action = request.data.get('action', '')
            
            if action == 'crawl_data':
                # 执行数据爬取
                result = self.crawler.run_full_crawl()
                return Response({
                    "code": 200,
                    "message": "数据爬取完成",
                    "data": result
                })
            
            elif action == 'update_knowledge':
                # 更新知识库
                new_data = request.data.get('new_data', [])
                success = self.service.update_knowledge_base(new_data)
                
                if success:
                    return Response({
                        "code": 200,
                        "message": "知识库更新成功",
                        "data": {"updated_count": len(new_data)}
                    })
                else:
                    return Response({
                        "code": 500,
                        "message": "知识库更新失败",
                        "data": None
                    }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
            
            else:
                return Response({
                    "code": 400,
                    "message": "无效的操作",
                    "data": None
                }, status=status.HTTP_400_BAD_REQUEST)
                
        except Exception as e:
            return Response({
                "code": 500,
                "message": f"操作失败: {str(e)}",
                "data": None
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    def get(self, request):
        """获取知识库信息"""
        try:
            category = request.GET.get('category', '')
            limit = int(request.GET.get('limit', 10))
            
            if category:
                # 按类别搜索
                results = self.service.search_by_category(category, limit)
            else:
                # 获取最近更新的知识
                days = int(request.GET.get('days', 7))
                results = self.service.get_recent_knowledge(days)
            
            return Response({
                "code": 200,
                "message": "获取知识库信息成功",
                "data": {
                    "results": results,
                    "count": len(results)
                }
            })
            
        except Exception as e:
            return Response({
                "code": 500,
                "message": f"获取知识库信息失败: {str(e)}",
                "data": None
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@method_decorator(csrf_exempt, name='dispatch')
class CustomerServiceAnalyticsView(APIView):
    """客服分析API"""
    
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.service = SmartCustomerService()
    
    def get(self, request):
        """获取查询分析数据"""
        try:
            days = int(request.GET.get('days', 30))
            analytics = self.service.get_query_analytics(days)
            
            return Response({
                "code": 200,
                "message": "获取分析数据成功",
                "data": analytics
            })
            
        except Exception as e:
            return Response({
                "code": 500,
                "message": f"获取分析数据失败: {str(e)}",
                "data": None
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    def post(self, request):
        """导出查询日志"""
        try:
            output_path = request.data.get('output_path', None)
            export_path = self.service.export_query_logs(output_path)
            
            if export_path:
                return Response({
                    "code": 200,
                    "message": "导出成功",
                    "data": {"export_path": export_path}
                })
            else:
                return Response({
                    "code": 500,
                    "message": "导出失败",
                    "data": None
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
                
        except Exception as e:
            return Response({
                "code": 500,
                "message": f"导出失败: {str(e)}",
                "data": None
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)